#pragma once
//@author A0105511Y
#include <exception>
#include <string>
#include <vector>
#include <iostream>
#include <time.h>
#include "Parser.h"
#include "Storage.h"
#include "History.h"
#include "Task.h"
#include "Action.h"
#include "CurrentDisplay.h"
#include "Logger.h"
#include "Utilities.h"


using namespace std;

class Logic {
private:
	static const string FEEDBACK_ADD;
	static const string FEEDBACK_SEARCH;
	static const string FEEDBACK_TODAY;
	static const string FEEDBACK_DELETE;
	static const string FEEDBACK_SORT_BY_TIME;
	static const string FEEDBACK_MODIFYING;
	static const string FEEDBACK_MODIFIED;
	static const string FEEDBACK_DONE;
	static const string FEEDBACK_UNDO;
	static const string FEEDBACK_ALL;

	static const string ERRORMESSAGE_INDEX_NOT_VALID;
	static const string ERRORMESSAGE_NOT_MODIFYING;
	static const string ERRORMESSAGE_INVALID_COMMAND;

	Parser parser;
	Storage storage;
	History history;

	CurrentDisplay currentDisplay;

	Logger& logger;

	Task *tempStore;
	Task dummyTask;

	bool isModifying;

	void addTask(string);
	void deleteTask(int);
	void searchTask(string);
	void modifyTask(string);
	void doneTask(int);

	void undoLastCommand();
	void displayToday();

	string getTargetTask(int);
	void setFeedback(CommandType, Task);
	bool isAPastDate(string targetDate);
	bool isToday(string targetDate);
	bool isAPastTime(string targetTime);

	// Pre: nil
	// Post: returns corresponding CommandType
	CommandType determineCommandType(string& command);

public:
	Logic(void);

	string processUserCommand(string);
	void updateStatus();

	vector<Task> getMainDisplay();
	vector<Task> getDoneDisplay();
	string getFeedback();

	// Pre: nil
	// Post: returns true if user input is valid, false otherwise
	bool isValidInput(string userInput);

	// Pre: nil
	// Post: returns true if current mainDisplay is searchResultDisplay
	bool isSearchResultDisplay() const;

	// Pre: nil
	// Post: returns searchKeyword
	string getSearchKeyword() const;
};

